package model.spawner;

import java.util.Random;

import model.Coordinate;
import model.entity.Entity2D;
import param.GameParam;
import param.GraphicsParam;

/**
 * Principale classe di un generico spowner 2D.
 * @author Jan
 *
 */
public abstract class Spawner2D extends Thread {
	
	private Entity2D[] entityBuffer = new Entity2D[GameParam.ENTITY_BUFFER_SIZE];
	private Entity2D[] entityBufferClone = new Entity2D[GameParam.ENTITY_BUFFER_SIZE];
	private long spawnDelay = GameParam.SPAWNER_INITIAL_DELAY;

	//Assegna ad ogni entita' la propria posizione nel buffer.
	private int index = 0;
	//Indica quante Entita' sono attive
	
	private int x;
	private int y;
	private boolean isRunning= false;
	
	
	@Override
	public synchronized void start() {
		isRunning = true;
		super.start();
	}

	
	/**
	 * Metodo astratto per definire la routine di generazione delle entita'.
	 */
	public abstract void createEntity();

	
	/**
	 * Fornisce un nuovo ID, aggiornando anche l'indice interno del buffer con una logica FIFO.
	 * @return
	 */
	public int generateID(){
//		System.out.println("ID generato: "+index);
		index++;
		if(index >= entityBuffer.length){
			//Si ricomincia a riempire il vettore da 0...
			index = 0;
		}
		return index;
	}
	
	/**
	 * Interrompe il ciclo interno nel thread dell'entita', lasciando che finisca, prima di intorrompere il thread.
	 * @param ID posizione nel buffer per recuperare l'entita' da eliminare.
	 */
	public void deleteActivity(int ID ){
		entityBuffer[ID].Kill();
		entityBuffer[ID] = null;
	}
	
	/**
	 * Aggiunge un entita' al buffer.
	 * @param entity
	 */
	public void insertEntity( Entity2D entity ){
		entityBuffer[entity.getEntityID()] = entity;
	}
	
	/**
	 * Genera delle coorinate casuali all'interno dell'intera area di rendering.
	 * @return
	 */
	public Coordinate generateFullRandomCooridates(){
		Random r = new Random();
		x = r.nextInt( GraphicsParam.GAME_WIDTH );
		y = r.nextInt( GraphicsParam.GAME_HEIGHT );
		return new Coordinate(x, y, 0);
	}
	
	
	/**
	 * Restituisce una copia del buffer di entita'.
	 * @return
	 */
	public Entity2D[]  cloneActalEntityBuffer(){
		System.arraycopy(entityBuffer, 0, entityBufferClone, 0, entityBuffer.length);
		return entityBufferClone;
	}
	
	/**
	 * Restituisce la dimensione del buffer.
	 * Nota: La dimensione viene definita al caricamento del gioco.
	 * @see GameParam per le impostazioni generali
	 * @return dimensione del buffer
	 */
	public int getBufferIndex(){
		return index;
	}
	
	
	@Override
	public void run() {
		
		while( isRunning ){
			generateID();
			createEntity();
			try {
				sleep(spawnDelay);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}

	
}
